//
//  Node.c
//  抽象二叉树
//
//  Created by chenyh on 2021/1/27.
//

#include "Node.h"
#include <stdlib.h>

static double _numnode_calc(Node *pThis)
{
    printf("numeric node %1f",((NumNode *)pThis)->_num);
    return ((NumNode *)pThis)->_num;
}
static void _numnode_cleanup(Node *pThis)
{
    printf("NumNode cleanup\n");
    free(pThis);
}
static double _addnode_calc(Node *pThis)
{
    printf("Adding...\n");
    AddNode *pAddNode = (AddNode *)pThis;
    return node_calc(pAddNode->isa.p_Left)+node_calc(pAddNode->isa.p_Right);
}
static double _multnode_calc(Node *pThis)
{
    printf("Multiplying...\n");
    MultNode * pMultNode = (MultNode *)pThis;
    return node_calc(pMultNode->isa.p_Left)+node_calc(pMultNode->isa.p_Right);
    
}
static void _binnode_cleanup(Node *pThis)
{
    printf("BinNode cleanup\n");
    BinNode *pBinNode = (BinNode *)pThis;
    node_cleanup(pBinNode->p_Left);
    node_cleanup(pBinNode->p_Right);
    free(pThis);
}

NumNode *newNumNode(double num)
{
    NumNode *pNumNode = malloc(sizeof(NumNode));
    if (pNumNode != NULL) {
        pNumNode->isa.node_calc = _numnode_calc;
        pNumNode->isa.node_cleanup = _numnode_cleanup;
        pNumNode->_num = num;
    }
    return pNumNode;
}


double node_calc(Node *pThis)
{
    return pThis->node_calc(pThis);
}

AddNode * newAddNode(Node *pLeft,Node *pRight)
{
    AddNode *pAddNode = malloc(sizeof(AddNode));
    if (pAddNode != NULL) {
        pAddNode->isa.isa.node_calc = _addnode_calc;
        
        pAddNode->isa.isa.node_cleanup = _binnode_cleanup;
        pAddNode->isa.p_Left = pLeft;
        pAddNode->isa.p_Right = pRight;
    }
    return pAddNode;
}

MultNode *newMultNode(Node *pLeft,Node *pRight)
{
    MultNode *pAddNode = malloc(sizeof(MultNode));
    if (pAddNode != NULL) {
        pAddNode->isa.isa.node_calc = _multnode_calc;
        pAddNode->isa.isa.node_cleanup = _binnode_cleanup;
        pAddNode->isa.p_Left = pLeft;
        pAddNode->isa.p_Right = pRight;
    }
    return pAddNode;
}
void node_cleanup(Node *pThis)
{
    pThis->node_cleanup(pThis);
}
